/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.jit.core.compile;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.inspur.edp.jit.api.compile.CompileContext;
import com.inspur.edp.jit.core.common.DirectoryManager;
import io.iec.edp.caf.common.JSONSerializer;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

public class ManifestUtil {
    private static ObjectWriter writer;

    /**
     * 更新Manifest.json信息
     *
     * @param context 编译上下文
     */
    public static void updateManifest(CompileContext context) {
        Manifest manifest = new Manifest();
        manifest.setVersion(context.getVersion());
        manifest.setCompileTime(new Date());
        manifest.setDescription(context.getDescription());
        manifest.setExtendProperties(context.getExtendProperties());
        try {
            String content = getObjectWriter().writeValueAsString(manifest);
            File file = getManifestJsonFile(context.getFunctionType(), context.getFunctionId());
            FileUtils.write(file, content, "utf-8", false);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 得到功能包的Manifest信息，如果功能包不存在或者manifest.json文件不存在，则返回null。
     *
     * @param functionType 功能包类型
     * @param functionId   功能包Id
     * @return 功能包的Manifest信息，如果功能包不存在或者manifest.json文件不存在，则返回null
     */
    public static Manifest getManifest(String functionType, String functionId) {
        File file = getManifestJsonFile(functionType, functionId);
        if (!file.exists()) {
            return null;
        }

        try {
            String content = FileUtils.readFileToString(file, "utf-8");
            if (content.isEmpty()) {
                return new Manifest();
            }

            return JSONSerializer.deserialize(content, Manifest.class);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    private static File getManifestJsonFile(String functionType, String functionId) {
        String functionDir = DirectoryManager.getJitDirectory(functionType, functionId);
        String path = DirectoryManager.joinFilePath(functionDir, "manifest.json");
        return new File(path);
    }

    private static ObjectWriter getObjectWriter() {
        if (writer == null) {
            //Copy from io.iec.edp.caf.common.JSONUtils
            //之所以不直接使用JSONUtils，是为了做让生成的字符串格式化
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
            objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
            objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
            objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
            objectMapper.configure(com.fasterxml.jackson.core.JsonGenerator.Feature.IGNORE_UNKNOWN, true);
            objectMapper.configure(com.fasterxml.jackson.core.JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
            objectMapper.configure(JsonParser.Feature.ALLOW_MISSING_VALUES, true);
            objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
            JavaTimeModule module = new JavaTimeModule();
            LocalDateTimeDeserializer deserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS a"));
            module.addDeserializer(LocalDateTime.class, deserializer);
            objectMapper.registerModule(module);

            //输出格式化
            writer = objectMapper.writerWithDefaultPrettyPrinter();
        }
        return writer;
    }
}
